case XEN_BLOCK_PROBE_BLK:
case XEN_BLOCK_PHYSDEV_GRANT:
case XEN_BLOCK_PHYSDEV_PROBE:
- if ( bret->status )
- printk(KERN_ALERT "Bad return from blkdev control request\n");
- xlblk_control_msg_pending = 0;
+ xlblk_control_msg_pending = bret->status;
break;
default:
if ( aligned_buf == NULL ) BUG();
memcpy(aligned_buf, buffer, size);
- xlblk_control_msg_pending = 1;
+ xlblk_control_msg_pending = 2;
spin_lock_irqsave(&io_request_lock, flags);
/* Note that size gets rounded up to a sector-sized boundary. */
if ( hypervisor_request(0, operation, aligned_buf, 0, (size+511)/512, 0) )
return -EAGAIN;
signal_requests_to_xen();
spin_unlock_irqrestore(&io_request_lock, flags);
- while ( xlblk_control_msg_pending ) barrier();
+ while ( xlblk_control_msg_pending == 2 ) barrier();
memcpy(buffer, aligned_buf, size);
free_page((unsigned long)aligned_buf);
- return 0;
+ return xlblk_control_msg_pending ? -EINVAL : 0;
}
case IOCTL_PRIVCMD_HYPERCALL:
{
privcmd_hypercall_t hypercall;
+
if ( copy_from_user(&hypercall, (void *)data, sizeof(hypercall)) )
return -EFAULT;
+
__asm__ __volatile__ (
"pushl %%ebx; pushl %%ecx; pushl %%edx; pushl %%esi; pushl %%edi; "
"movl 4(%%eax),%%ebx ;"
privcmd_blkmsg_t blkmsg;
char *kbuf;
int ret;
+
if ( copy_from_user(&blkmsg, (void *)data, sizeof(blkmsg)) )
return -EFAULT;
+
if ( blkmsg.buf_size > PAGE_SIZE )
return -EINVAL;
+
if ( (kbuf = kmalloc(blkmsg.buf_size, GFP_KERNEL)) == NULL )
return -ENOMEM;
+
if ( copy_from_user(kbuf, blkmsg.buf, blkmsg.buf_size) ) {
kfree(kbuf);
return -EFAULT;
}
+
ret = xenolinux_control_msg((int)blkmsg.op, kbuf, blkmsg.buf_size);
if ( ret != 0 ) {
kfree(kbuf);
return ret;
}
+
if ( copy_to_user(blkmsg.buf, kbuf, blkmsg.buf_size) ) {
kfree(kbuf);
return -EFAULT;
}
+
kfree(kbuf);
}
break;
case IOCTL_PRIVCMD_LINDEV_TO_XENDEV:
+ {
ret = (int)xldev_to_physdev((kdev_t)data);
+ }
+ break;
case IOCTL_PRIVCMD_XENDEV_TO_LINDEV:
+ {
ret = (int)physdev_to_xldev((unsigned short)data);
+ }
+ break;
default:
{
#ifndef __PROC_CMD_H__
#define __PROC_CMD_H__
-#define IOCTL_PRIVCMD_HYPERCALL 0
-#define IOCTL_PRIVCMD_BLKMSG 1
-#define IOCTL_PRIVCMD_LINDEV_TO_XENDEV 2
-#define IOCTL_PRIVCMD_XENDEV_TO_LINDEV 3
-
typedef struct privcmd_hypercall
{
unsigned long op;
int buf_size;
} privcmd_blkmsg_t;
+#define IOCTL_PRIVCMD_HYPERCALL \
+ _IOC(_IOC_NONE, 'P', 0, sizeof(privcmd_hypercall_t))
+#define IOCTL_PRIVCMD_BLKMSG \
+ _IOC(_IOC_NONE, 'P', 1, sizeof(privcmd_blkmsg_t))
+#define IOCTL_PRIVCMD_LINDEV_TO_XENDEV \
+ _IOC(_IOC_NONE, 'P', 2, sizeof(unsigned short))
+#define IOCTL_PRIVCMD_XENDEV_TO_LINDEV \
+ _IOC(_IOC_NONE, 'P', 3, sizeof(unsigned short))
+
#endif /* __PROC_CMD_H__ */